package com.yueka.utils;

import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;
import javax.crypto.SecretKey;
import java.time.Instant;
import java.util.Date;
import java.util.Map;

/**
 * JWT 工具类 (jjwt 0.12.x + Java 17)
 */
public class JwtUtils {

    // 密钥（推荐从环境变量或配置中心获取）
    private static final SecretKey SECRET_KEY = Keys.hmacShaKeyFor("your-256-bit-secret-key-1234567890".getBytes());
    // Token有效期（单位：秒）
    private static final long EXPIRATION_SECONDS = 3600;

    /**
     * 生成JWT
     * @param subject 用户标识（如用户ID）
     * @param claims  自定义声明（额外数据）
     * @return JWT字符串
     */
    public static String generateToken(String subject, Map<String, Object> claims) {
        return Jwts.builder()
                .subject(subject)
                .claims(claims)
                .issuedAt(Date.from(Instant.now()))
                .expiration(Date.from(Instant.now().plusSeconds(EXPIRATION_SECONDS)))
                .signWith(SECRET_KEY, Jwts.SIG.HS256)
                .compact();
    }

    /**
     * 解析JWT
     * @param token JWT字符串
     * @return 解析后的 Claims 对象
     * @throws JwtException 解析失败时抛出异常
     */
    public static Claims parseToken(String token) throws JwtException {
        return Jwts.parser()
                .verifyWith(SECRET_KEY)
                .build()
                .parseSignedClaims(token)
                .getPayload();
    }

    /**
     * 快速获取用户标识
     */
    public static String getSubject(String token) {
        return parseToken(token).getSubject();
    }

    /**
     * 验证Token有效性
     */
    public static boolean validateToken(String token) {
        try {
            parseToken(token);
            return true;
        } catch (JwtException e) {
            return false;
        }
    }

    // 使用示例
    public static void main(String[] args) {
        // 生成Token
        var token = generateToken("user123", Map.of("role", "admin"));
        System.out.println("Generated Token:\n" + token);

        // 解析验证
        if (validateToken(token)) {
            var claims = parseToken(token);
            System.out.printf("""
                    Subject: %s
                    Role: %s
                    Expiration: %s
                    """, claims.getSubject(), claims.get("role"), claims.getExpiration());
        }
    }
}